package com.zyg.config;

import com.zyg.filter.JwtAuthorizationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
public class SecurityConfig {

    // 从配置文件中读取 JWT 秘钥
    @Value("${jwt.secret}")
    private String jwtSecret;

    @Autowired
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

    // 配置 AuthenticationManager，用于认证
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    // 配置 SecurityFilterChain，添加 JWT 过滤器
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                //login接口不会被jwtAuthenticationEntryPoint捕获，即使没有token不会进入token认证失败验证
                .antMatchers("/auth/login").permitAll() // 允许访问登录接口
                .anyRequest().authenticated() // 其他请求需要认证
                .and()
                //UsernamePasswordAuthenticationFilter 是 Spring Security 提供的一个内置过滤器，主要用于处理基于表单的认证（例如，用户名和密码的认证）。它的作用是接收 HTTP 请求中的用户名和密码，
                // 并根据这些信息执行认证逻辑。如果认证成功，它会将 Authentication 对象放入 SecurityContext 中，以便后续的处理。
                .addFilterBefore(new JwtAuthorizationFilter(jwtSecret), UsernamePasswordAuthenticationFilter.class)

                //多个过滤器
//                .addFilterBefore(new CustomLoggingFilter(), UsernamePasswordAuthenticationFilter.class) // 在 UsernamePasswordAuthenticationFilter 前执行
//                .addFilterBefore(new JwtAuthorizationFilter(jwtSecret), CustomLoggingFilter.class) // 在 CustomLoggingFilter 前执行
//                .addFilterAfter(new CustomAuthFilter(), JwtAuthorizationFilter.class) // 在 JwtAuthorizationFilter 后执行
                // AuthenticationEntryPoint 接口的作用是当用户未通过身份验证（例如，JWT 验证失败时），Spring Security 会调用该接口的 commence() 方法，这样就可以进行自定义的异常处理或跳转处理。
                .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint); // 设置自定义的 AuthenticationEntryPoint
        return http.build();
    }

    // 配置 BCrypt 密码编码器（可选）
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
